{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# 线性回归 -实现线性回归房价预测"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "e6b0b74f92ccc642"
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 一、导入相关包"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "cab6774b4664b941"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "# from sklearn.datasets import load_boston  # version 1.2.后弃用\n",
    "from sklearn.preprocessing import scale\n",
    "import pandas as pd\n",
    "import numpy as np"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:52.150373400Z",
     "start_time": "2024-03-28T11:04:52.040123700Z"
    }
   },
   "id": "498a9998b05befb4",
   "execution_count": 6
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 二、定义常量"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "26a1857199796051"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "learning_rate = 0.01  # 学习率\n",
    "epochs = 10000  # 迭代次数\n",
    "display_epoch = epochs // 20  # 控制训练过程中数据显示的频率\n",
    "n_train = 300  # 60%训练集\n",
    "n_valid = 100  # 20%验证集"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:52.173004600Z",
     "start_time": "2024-03-28T11:04:52.157946800Z"
    }
   },
   "id": "5e4f48b7abe1a2f0",
   "execution_count": 7
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 三、数据集处理"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "2049917590685b45"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "n_train: 300\n",
      "n_valid: 100\n",
      "n_test: 106\n"
     ]
    }
   ],
   "source": [
    "# 下载Boston Housing数据集\n",
    "url = \"https://archive.ics.uci.edu/ml/machine-learning-databases/housing/housing.data\"\n",
    "column_names = [\"CRIM\", \"ZN\", \"INDUS\", \"CHAS\", \"NOX\", \"RM\", \"AGE\", \"DIS\", \"RAD\", \"TAX\", \"PTRATIO\", \"B\", \"LSTAT\", \"MEDV\"]\n",
    "\n",
    "# 加载数据到pandas DataFrame\n",
    "data = pd.read_csv(url, header=None, delim_whitespace=True, names=column_names)\n",
    "# 分割特征和目标变量\n",
    "features = data.iloc[:, :-1]  # 特征\n",
    "prices = data[\"MEDV\"]  # 目标（房价）\n",
    "\n",
    "# 如果需要将数据转换为NumPy数组以便在scikit-learn中使用\n",
    "prices = prices.to_numpy()\n",
    "\n",
    "# 训练集、验证集和测试集数量\n",
    "n_test = len(features) - n_train - n_valid  #测试集\n",
    "print('n_train:', n_train)\n",
    "print('n_valid:', n_valid)\n",
    "print('n_test:', n_test)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:53.631307400Z",
     "start_time": "2024-03-28T11:04:52.178007900Z"
    }
   },
   "id": "18c3ba2025f5589b",
   "execution_count": 8
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[24.  21.6 34.7 33.4 36.2 28.7 22.9 27.1 16.5 18.9 15.  18.9 21.7 20.4\n",
      " 18.2 19.9 23.1 17.5 20.2 18.2 13.6 19.6 15.2 14.5 15.6 13.9 16.6 14.8\n",
      " 18.4 21.  12.7 14.5 13.2 13.1 13.5 18.9 20.  21.  24.7 30.8 34.9 26.6\n",
      " 25.3 24.7 21.2 19.3 20.  16.6 14.4 19.4 19.7 20.5 25.  23.4 18.9 35.4\n",
      " 24.7 31.6 23.3 19.6 18.7 16.  22.2 25.  33.  23.5 19.4 22.  17.4 20.9\n",
      " 24.2 21.7 22.8 23.4 24.1 21.4 20.  20.8 21.2 20.3 28.  23.9 24.8 22.9\n",
      " 23.9 26.6 22.5 22.2 23.6 28.7 22.6 22.  22.9 25.  20.6 28.4 21.4 38.7\n",
      " 43.8 33.2 27.5 26.5 18.6 19.3 20.1 19.5 19.5 20.4 19.8 19.4 21.7 22.8\n",
      " 18.8 18.7 18.5 18.3 21.2 19.2 20.4 19.3 22.  20.3 20.5 17.3 18.8 21.4\n",
      " 15.7 16.2 18.  14.3 19.2 19.6 23.  18.4 15.6 18.1 17.4 17.1 13.3 17.8\n",
      " 14.  14.4 13.4 15.6 11.8 13.8 15.6 14.6 17.8 15.4 21.5 19.6 15.3 19.4\n",
      " 17.  15.6 13.1 41.3 24.3 23.3 27.  50.  50.  50.  22.7 25.  50.  23.8\n",
      " 23.8 22.3 17.4 19.1 23.1 23.6 22.6 29.4 23.2 24.6 29.9 37.2 39.8 36.2\n",
      " 37.9 32.5 26.4 29.6 50.  32.  29.8 34.9 37.  30.5 36.4 31.1 29.1 50.\n",
      " 33.3 30.3 34.6 34.9 32.9 24.1 42.3 48.5 50.  22.6 24.4 22.5 24.4 20.\n",
      " 21.7 19.3 22.4 28.1 23.7 25.  23.3 28.7 21.5 23.  26.7 21.7 27.5 30.1\n",
      " 44.8 50.  37.6 31.6 46.7 31.5 24.3 31.7 41.7 48.3 29.  24.  25.1 31.5\n",
      " 23.7 23.3 22.  20.1 22.2 23.7 17.6 18.5 24.3 20.5 24.5 26.2 24.4 24.8\n",
      " 29.6 42.8 21.9 20.9 44.  50.  36.  30.1 33.8 43.1 48.8 31.  36.5 22.8\n",
      " 30.7 50.  43.5 20.7 21.1 25.2 24.4 35.2 32.4 32.  33.2 33.1 29.1 35.1\n",
      " 45.4 35.4 46.  50.  32.2 22.  20.1 23.2 22.3 24.8 28.5 37.3 27.9 23.9\n",
      " 21.7 28.6 27.1 20.3 22.5 29.  24.8 22.  26.4 33.1 36.1 28.4 33.4 28.2\n",
      " 22.8 20.3 16.1 22.1 19.4 21.6 23.8 16.2 17.8 19.8 23.1 21.  23.8 23.1\n",
      " 20.4 18.5 25.  24.6 23.  22.2 19.3 22.6 19.8 17.1 19.4 22.2 20.7 21.1\n",
      " 19.5 18.5 20.6 19.  18.7 32.7 16.5 23.9 31.2 17.5 17.2 23.1 24.5 26.6\n",
      " 22.9 24.1 18.6 30.1 18.2 20.6 17.8 21.7 22.7 22.6 25.  19.9 20.8 16.8\n",
      " 21.9 27.5 21.9 23.1 50.  50.  50.  50.  50.  13.8 13.8 15.  13.9 13.3\n",
      " 13.1 10.2 10.4 10.9 11.3 12.3  8.8  7.2 10.5  7.4 10.2 11.5 15.1 23.2\n",
      "  9.7 13.8 12.7 13.1 12.5  8.5  5.   6.3  5.6  7.2 12.1  8.3  8.5  5.\n",
      " 11.9 27.9 17.2 27.5 15.  17.2 17.9 16.3  7.   7.2  7.5 10.4  8.8  8.4\n",
      " 16.7 14.2 20.8 13.4 11.7  8.3 10.2 10.9 11.   9.5 14.5 14.1 16.1 14.3\n",
      " 11.7 13.4  9.6  8.7  8.4 12.8 10.5 17.1 18.4 15.4 10.8 11.8 14.9 12.6\n",
      " 14.1 13.  13.4 15.2 16.1 17.8 14.9 14.1 12.7 13.5 14.9 20.  16.4 17.7\n",
      " 19.5 20.2 21.4 19.9 19.  19.1 19.1 20.1 19.9 19.6 23.2 29.8 13.8 13.3\n",
      " 16.7 12.  14.6 21.4 23.  23.7 25.  21.8 20.6 21.2 19.1 20.6 15.2  7.\n",
      "  8.1 13.6 20.1 21.8 24.5 23.1 19.7 18.3 21.2 17.5 16.8 22.4 20.6 23.9\n",
      " 22.  11.9]\n"
     ]
    }
   ],
   "source": [
    "print(prices)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:53.649505800Z",
     "start_time": "2024-03-28T11:04:53.629316100Z"
    }
   },
   "id": "da83017e857c8de5",
   "execution_count": 9
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "        CRIM    ZN  INDUS  CHAS    NOX     RM   AGE     DIS  RAD    TAX  \\\n",
      "0    0.00632  18.0   2.31     0  0.538  6.575  65.2  4.0900    1  296.0   \n",
      "1    0.02731   0.0   7.07     0  0.469  6.421  78.9  4.9671    2  242.0   \n",
      "2    0.02729   0.0   7.07     0  0.469  7.185  61.1  4.9671    2  242.0   \n",
      "3    0.03237   0.0   2.18     0  0.458  6.998  45.8  6.0622    3  222.0   \n",
      "4    0.06905   0.0   2.18     0  0.458  7.147  54.2  6.0622    3  222.0   \n",
      "..       ...   ...    ...   ...    ...    ...   ...     ...  ...    ...   \n",
      "501  0.06263   0.0  11.93     0  0.573  6.593  69.1  2.4786    1  273.0   \n",
      "502  0.04527   0.0  11.93     0  0.573  6.120  76.7  2.2875    1  273.0   \n",
      "503  0.06076   0.0  11.93     0  0.573  6.976  91.0  2.1675    1  273.0   \n",
      "504  0.10959   0.0  11.93     0  0.573  6.794  89.3  2.3889    1  273.0   \n",
      "505  0.04741   0.0  11.93     0  0.573  6.030  80.8  2.5050    1  273.0   \n",
      "\n",
      "     PTRATIO       B  LSTAT  \n",
      "0       15.3  396.90   4.98  \n",
      "1       17.8  396.90   9.14  \n",
      "2       17.8  392.83   4.03  \n",
      "3       18.7  394.63   2.94  \n",
      "4       18.7  396.90   5.33  \n",
      "..       ...     ...    ...  \n",
      "501     21.0  391.99   9.67  \n",
      "502     21.0  396.90   9.08  \n",
      "503     21.0  396.90   5.64  \n",
      "504     21.0  393.45   6.48  \n",
      "505     21.0  396.90   7.88  \n",
      "\n",
      "[506 rows x 13 columns]\n"
     ]
    }
   ],
   "source": [
    "print(features)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:53.701622200Z",
     "start_time": "2024-03-28T11:04:53.643522400Z"
    }
   },
   "id": "17f371a87cffae87",
   "execution_count": 10
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(506, 13)\n"
     ]
    }
   ],
   "source": [
    "# 特征维度\n",
    "print(features.shape)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:53.704246600Z",
     "start_time": "2024-03-28T11:04:53.678429700Z"
    }
   },
   "id": "33f49bb9d6af5c3d",
   "execution_count": 11
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tf.Tensor(\n",
      "[[-0.6411311   0.10080399 -1.0306702  ... -1.002688    0.4205457\n",
      "  -0.92348367]\n",
      " [-0.60977125 -0.5935092  -0.28321603 ...  0.09274682  0.4205457\n",
      "  -0.25234807]\n",
      " [-0.6098011  -0.5935092  -0.28321603 ...  0.09274682  0.32645613\n",
      "  -1.0767478 ]\n",
      " ...\n",
      " [-0.43986905 -0.5935092   0.79242706 ... -0.6959663   0.4205457\n",
      "   0.82856745]\n",
      " [-0.55396885  2.1065977  -1.0416622  ... -1.221775   -0.24201132\n",
      "  -0.925097  ]\n",
      " [-0.5674899   2.1065977  -1.0416622  ... -1.221775   -0.16479777\n",
      "  -0.962203  ]], shape=(300, 13), dtype=float32)\n",
      "\n",
      "[24.  21.6 34.7 33.4 36.2 28.7 22.9 27.1 16.5 18.9 15.  18.9 21.7 20.4\n",
      " 18.2 19.9 23.1 17.5 20.2 18.2 13.6 19.6 15.2 14.5 15.6 13.9 16.6 14.8\n",
      " 18.4 21.  12.7 14.5 13.2 13.1 13.5 18.9 20.  21.  24.7 30.8 34.9 26.6\n",
      " 25.3 24.7 21.2 19.3 20.  16.6 14.4 19.4 19.7 20.5 25.  23.4 18.9 35.4\n",
      " 24.7 31.6 23.3 19.6 18.7 16.  22.2 25.  33.  23.5 19.4 22.  17.4 20.9\n",
      " 24.2 21.7 22.8 23.4 24.1 21.4 20.  20.8 21.2 20.3 28.  23.9 24.8 22.9\n",
      " 23.9 26.6 22.5 22.2 23.6 28.7 22.6 22.  22.9 25.  20.6 28.4 21.4 38.7\n",
      " 43.8 33.2 27.5 26.5 18.6 19.3 20.1 19.5 19.5 20.4 19.8 19.4 21.7 22.8\n",
      " 18.8 18.7 18.5 18.3 21.2 19.2 20.4 19.3 22.  20.3 20.5 17.3 18.8 21.4\n",
      " 15.7 16.2 18.  14.3 19.2 19.6 23.  18.4 15.6 18.1 17.4 17.1 13.3 17.8\n",
      " 14.  14.4 13.4 15.6 11.8 13.8 15.6 14.6 17.8 15.4 21.5 19.6 15.3 19.4\n",
      " 17.  15.6 13.1 41.3 24.3 23.3 27.  50.  50.  50.  22.7 25.  50.  23.8\n",
      " 23.8 22.3 17.4 19.1 23.1 23.6 22.6 29.4 23.2 24.6 29.9 37.2 39.8 36.2\n",
      " 37.9 32.5 26.4 29.6 50.  32.  29.8 34.9 37.  30.5 36.4 31.1 29.1 50.\n",
      " 33.3 30.3 34.6 34.9 32.9 24.1 42.3 48.5 50.  22.6 24.4 22.5 24.4 20.\n",
      " 21.7 19.3 22.4 28.1 23.7 25.  23.3 28.7 21.5 23.  26.7 21.7 27.5 30.1\n",
      " 44.8 50.  37.6 31.6 46.7 31.5 24.3 31.7 41.7 48.3 29.  24.  25.1 31.5\n",
      " 23.7 23.3 22.  20.1 22.2 23.7 17.6 18.5 24.3 20.5 24.5 26.2 24.4 24.8\n",
      " 29.6 42.8 21.9 20.9 44.  50.  36.  30.1 33.8 43.1 48.8 31.  36.5 22.8\n",
      " 30.7 50.  43.5 20.7 21.1 25.2 24.4 35.2 32.4 32.  33.2 33.1 29.1 35.1\n",
      " 45.4 35.4 46.  50.  32.2 22.  20.1 23.2 22.3 24.8 28.5 37.3 27.9 23.9\n",
      " 21.7 28.6 27.1 20.3 22.5 29. ]\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "scale() 函数实现的是特征缩放的标准化处理，它将每个特征减去其平均值并除以标准差，使得处理后的数据具有零均值和单位方差，即转换为标准正态分布。\n",
    "\"\"\"\n",
    "# 训练集样本 前60%\n",
    "train_features = tf.cast(scale(features[:n_train]), dtype=tf.float32)  #将训练集转换为float32类型\n",
    "train_prices = prices[:n_train]\n",
    "print(train_features)\n",
    "print()\n",
    "print(train_prices)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:54.890811100Z",
     "start_time": "2024-03-28T11:04:53.690651600Z"
    }
   },
   "id": "d1c8d8fe7353e636",
   "execution_count": 12
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# 验证集样本 中间20%\n",
    "valid_features = tf.cast(scale(features[n_train:n_train + n_valid]), dtype=tf.float32)\n",
    "valid_prices = prices[n_train:n_train + n_valid]"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:54.891808800Z",
     "start_time": "2024-03-28T11:04:54.872043100Z"
    }
   },
   "id": "b8981ea4478563ff",
   "execution_count": 13
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "# 测试集样本 中间20%\n",
    "test_features = tf.cast(scale(features[n_train + n_valid:n_train + n_valid + n_test]), dtype=tf.float32)\n",
    "test_prices = prices[n_train + n_valid:n_train + n_valid + n_test]"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:54.925137200Z",
     "start_time": "2024-03-28T11:04:54.889814700Z"
    }
   },
   "id": "ce360afd5848edba",
   "execution_count": 14
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:54.925918700Z",
     "start_time": "2024-03-28T11:04:54.905057700Z"
    }
   },
   "id": "f8685f07e44c3d25",
   "execution_count": 14
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 四、定义函数"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "1d0191c42d91541f"
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 1.回归模型 \n",
    "\n",
    "这段代码定义了一个名为 prediction 的函数，它使用 TensorFlow 库实现了一个简单的线性模型预测。输入参数包括：\n",
    "  x: 输入变量，通常是一个形状为 [batch_size, input_features] 的张量，代表一批样本的特征数据。\n",
    "  weight: 权重矩阵，一个形状为 [input_features, output_features] 的张量，用于与输入特征相乘，以计算预测值。\n",
    "  bias: 偏置向量（或标量），形状为 [output_features] 或 [1] 的张量，用于在加权和之后添加偏置项。\n",
    "  \n",
    "函数内部的操作是：\n",
    "    使用 tf.matmul(x, weight) 计算输入特征与权重矩阵的矩阵乘积，得到初步的预测结果。\n",
    "    然后通过 tf.add() 函数将上述结果与偏置向量相加，得到最终的预测输出。\n",
    "    所以该函数整体上实现了对输入数据进行一次线性变换并加上偏置项的过程，即 y = Wx + b，这是许多机器学习模型中最基本的预测层结构。"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "c1b9306ab44d146c"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "def prediction(x, weight, bias):\n",
    "    return tf.add(tf.matmul(x, weight), bias)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:54.950375800Z",
     "start_time": "2024-03-28T11:04:54.918838600Z"
    }
   },
   "id": "773e2ee8d8f383a7",
   "execution_count": 15
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 2.损失函数\n",
    "这段代码定义了一个名为 loss 的函数，用于计算给定输入数据 x 和真实标签 y 时的模型预测误差，并使用均方根误差（Root Mean Squared Error, RMSE）作为损失函数。\n",
    "函数首先调用之前定义的 prediction 函数，该函数接收输入特征 x、权重 weight 和偏置 bias 作为参数，返回基于这些参数的预测值。\n",
    "计算预测值与实际标签值之间的误差：error = prediction(x, weight, bias) - y。这里的误差是预测输出和实际目标值之间的差异。\n",
    "将误差平方以得到每个样本点的平方误差：squared_error = tf.square(error)。\n",
    "使用 TensorFlow 中的 tf.reduce_mean() 函数计算所有样本点的平方误差的平均值。input_tensor=squared_error 指定了要计算均值的张量。\n",
    "最后，对平均平方误差取平方根，从而得到均方根误差（RMSE），这是回归任务中常用的评估指标，它能够度量模型预测值与真实值之间的平均距离。\n",
    "因此，这个 loss 函数可以被用于训练神经网络或其他机器学习模型，在优化过程中计算损失并指导模型参数更新。"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "1994b7b4ca60bc33"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "def loss(x, y, weight, bias):\n",
    "    error = prediction(x, weight, bias) - y  #误差\n",
    "    squared_error = tf.square(error)\n",
    "    return tf.sqrt(tf.reduce_mean(input_tensor=squared_error))  # 计算均方根误差\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:54.951824500Z",
     "start_time": "2024-03-28T11:04:54.936412Z"
    }
   },
   "id": "81f35f5980e7e801",
   "execution_count": 16
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 3.梯度函数\n",
    "这段代码定义了一个名为 grad 的函数，用于计算给定输入特征 x、真实标签 y、权重参数 weight 和偏置参数 bias 时损失函数关于权重和偏置的梯度。\n",
    "使用 TensorFlow 中的 tf.GradientTape() 上下文管理器来创建一个梯度记录环境。在该环境下执行的操作将被自动跟踪以计算梯度。\n",
    "在这个梯度记录环境中，调用之前定义的 loss 函数，并传入输入特征 x、真实标签 y、权重 weight 和偏置 bias 参数，从而计算模型的损失值（这里假设 loss 函数返回的是均方根误差）。\n",
    "结束 tf.GradientTape() 上下文后，使用 tape.gradient(loss_, [weight, bias]) 来计算损失函数关于权重和偏置的梯度。这里的 loss_ 是在上下文中计算得到的损失值，[weight, bias] 是需要求梯度的变量列表。\n",
    "函数最终返回的是一个包含权重梯度和偏置梯度的元组或列表。这些梯度在训练神经网络时会被用来更新模型参数，以便通过梯度下降或其他优化算法最小化损失函数。"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "42cbbc7904948b63"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "def grad(x, y, weight, bias):\n",
    "    with tf.GradientTape() as tape:\n",
    "        loss_ = loss(x, y, weight, bias)\n",
    "    return tape.gradient(loss_, [weight, bias])"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:54.991404500Z",
     "start_time": "2024-03-28T11:04:54.950823300Z"
    }
   },
   "id": "1faec9b1a6a4fdfb",
   "execution_count": 17
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:54.993398800Z",
     "start_time": "2024-03-28T11:04:54.966333500Z"
    }
   },
   "id": "5f1bbb60b65e374c",
   "execution_count": 17
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 五、模型训练"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "dc00f22a741eee64"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:55.011372200Z",
     "start_time": "2024-03-28T11:04:54.982288900Z"
    }
   },
   "id": "4cb0f436ab5dfcf2",
   "execution_count": 17
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 1.初始化W、B"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "f7f4248a3f167933"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<tf.Variable 'Variable:0' shape=(13, 1) dtype=float32, numpy=\n",
      "array([[ 0.03564682],\n",
      "       [-0.15726465],\n",
      "       [ 0.41638276],\n",
      "       [-0.01476731],\n",
      "       [-0.39520973],\n",
      "       [ 0.5985768 ],\n",
      "       [ 0.04433297],\n",
      "       [ 0.63746107],\n",
      "       [-0.15186767],\n",
      "       [-1.3258883 ],\n",
      "       [ 0.5952723 ],\n",
      "       [-0.6824988 ],\n",
      "       [ 0.76500803]], dtype=float32)> <tf.Variable 'Variable:0' shape=(1,) dtype=float32, numpy=array([0.], dtype=float32)>\n",
      "\n",
      "Initial Loss:27.037\n"
     ]
    }
   ],
   "source": [
    "# W = tf.Variable(tf.random.normal[13, 1])\n",
    "W = tf.Variable(tf.random.normal(shape=(13, 1), mean=0.0, stddev=1.0))\n",
    "B = tf.Variable(tf.zeros(1))\n",
    "print(W, B)\n",
    "print()\n",
    "print('Initial Loss:{:.3f}'.format(loss(train_features, train_prices, W, B)))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:55.406332800Z",
     "start_time": "2024-03-28T11:04:54.997388400Z"
    }
   },
   "id": "628554639d636bb4",
   "execution_count": 18
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "x,y = train_data()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:04:55.450818500Z",
     "start_time": "2024-03-28T11:04:55.405366900Z"
    }
   },
   "id": "d657d35479277227",
   "execution_count": 18
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 2.训练模型"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "3ed6344fc6920926"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Validation loss after epoch: 00 * 100,loss:22.819\n",
      "Validation loss after epoch: 05 * 100,loss:18.660\n",
      "Validation loss after epoch: 10 * 100,loss:15.089\n",
      "Validation loss after epoch: 15 * 100,loss:12.559\n",
      "Validation loss after epoch: 20 * 100,loss:11.279\n",
      "Validation loss after epoch: 25 * 100,loss:10.778\n",
      "Validation loss after epoch: 30 * 100,loss:10.591\n",
      "Validation loss after epoch: 35 * 100,loss:10.520\n",
      "Validation loss after epoch: 40 * 100,loss:10.492\n",
      "Validation loss after epoch: 45 * 100,loss:10.481\n",
      "Validation loss after epoch: 50 * 100,loss:10.477\n",
      "Validation loss after epoch: 55 * 100,loss:10.475\n",
      "Validation loss after epoch: 60 * 100,loss:10.474\n",
      "Validation loss after epoch: 65 * 100,loss:10.474\n",
      "Validation loss after epoch: 70 * 100,loss:10.474\n",
      "Validation loss after epoch: 75 * 100,loss:10.474\n",
      "Validation loss after epoch: 80 * 100,loss:10.474\n",
      "Validation loss after epoch: 85 * 100,loss:10.474\n",
      "Validation loss after epoch: 90 * 100,loss:10.474\n",
      "Validation loss after epoch: 95 * 100,loss:10.474\n"
     ]
    }
   ],
   "source": [
    "for epoch in range(epochs):\n",
    "    dataW, dataB = grad(train_features, test_prices, W, B)\n",
    "    #微调\n",
    "    change_W = dataW * learning_rate\n",
    "    change_B = dataB * learning_rate\n",
    "    W.assign_sub(change_W)\n",
    "    B.assign_sub(change_B)\n",
    "    #显示loss变化过程\n",
    "    if epoch == 0 or epoch % display_epoch == 0:\n",
    "        epoch_print = int(epoch if epoch == 0 else epoch / 100)\n",
    "        print('Validation loss after epoch: {:02d} * 100,loss:{:.3f}'.format(epoch_print, loss(valid_features, valid_prices, W, B)))\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:05:35.456125100Z",
     "start_time": "2024-03-28T11:04:55.427422800Z"
    }
   },
   "id": "c82d2d2e5b02777b",
   "execution_count": 19
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tf.Tensor(5.3157887, shape=(), dtype=float32)\n",
      "tf.Tensor(13.183573, shape=(), dtype=float32)\n"
     ]
    }
   ],
   "source": [
    "print(loss(test_features,test_prices,W,B)) #测试集的均根方误差\n",
    "print(loss(train_features,train_prices,W,B)) #训练集的均根方误差"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:05:35.555866500Z",
     "start_time": "2024-03-28T11:05:35.450083300Z"
    }
   },
   "id": "5a0541db265cfc9d",
   "execution_count": 20
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[-0.00056311]\n",
      " [-0.00576673]\n",
      " [ 0.00379072]\n",
      " [-0.0006095 ]\n",
      " [-0.00328006]\n",
      " [ 0.01486138]\n",
      " [-0.00957474]\n",
      " [ 0.00219968]\n",
      " [-0.00070397]\n",
      " [ 0.001853  ]\n",
      " [-0.00235247]\n",
      " [-0.00071959]\n",
      " [ 0.01716748]] [15.733709]\n"
     ]
    }
   ],
   "source": [
    "print(W.numpy(),B.numpy())"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:05:35.598748600Z",
     "start_time": "2024-03-28T11:05:35.557859300Z"
    }
   },
   "id": "1432981dc31fcda",
   "execution_count": 21
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 六、将预测结果与实际房价进行对比\n"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "ef4a5dbeaae8e9b6"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "23.0 tf.Tensor([15.740156], shape=(1,), dtype=float32)\n"
     ]
    }
   ],
   "source": [
    "\"\"\"\n",
    "这段代码是用于预测模型输出，并将预测结果与实际值进行比较。以下是详细解释：\n",
    "e_h = 80：这里定义了一个变量 e_h，赋值为整数 80。这个变量可能代表一个时间步（例如在时间序列预测中）或者样本索引。\n",
    "y = test_prices[e_h]：从测试集价格数据 test_prices 中取出第 e_h 个位置的元素，并将其赋值给变量 y。这个 y 通常表示真实的目标值或标签。\n",
    "y_pred = prediction(test_features, W.numpy(), B.numpy())[e_h]：\n",
    "prediction 函数在这里被用来根据输入特征 test_features 和已训练好的权重矩阵 W、偏置向量 B 来预测目标值。\n",
    "W.numpy() 和 B.numpy() 是将 TensorFlow 张量转换成 NumPy 数组，以便能在 prediction 函数中使用。\n",
    "[e_h] 表示从 prediction 函数返回的预测结果中选取第 e_h 个位置的预测值，并将其赋值给变量 y_pred。\n",
    "print(y, y_pred)：最后，打印出实际目标值 y 和预测值 y_pred，便于观察和评估模型预测性能。\n",
    "\"\"\"\n",
    "e_h = 80\n",
    "y = test_prices[e_h]\n",
    "y_pred = prediction(test_features,W.numpy(),B.numpy())[e_h]\n",
    "print(y,y_pred)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:05:35.639756200Z",
     "start_time": "2024-03-28T11:05:35.575812600Z"
    }
   },
   "id": "e9c9bfcdaa489952",
   "execution_count": 22
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-03-28T11:05:35.650741700Z",
     "start_time": "2024-03-28T11:05:35.636763400Z"
    }
   },
   "id": "15b6cca9e0602529",
   "execution_count": 22
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
